home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / オンラインウェア / BUS / BibTeX 1.06 FAT.sit / BibTeX ƒ / Source code / bibutils.cc < prev    next >
C/C++ Source or Header  |  1996-06-03  |  40KB  |  821 lines

  1. //###################################################################
  2. //
  3. // FILE: "bibutils.cc"
  4. //                                   created: 31/1/96 {12:23:51 am} 
  5. //                               last update: 3/6/96 {9:55:57 pm} 
  6. // Author: Vince Darley
  7. // E-mail: <mailto:vince@das.harvard.edu>
  8. //   mail: Division of Applied Sciences, Harvard University
  9. //         Oxford Street, Cambridge MA 02138, USA
  10. // <http://www.das.harvard.edu/users/students/Vincent_Darley/>
  11. // 
  12. // See header file for further information
  13. //###################################################################
  14.  
  15. // Based on code from Rick Zaccone. This file is kind of an interface between the
  16. // powerplant application and the BibTeX source code.
  17. // There's old stuff hanging about which needs to be cleared out!
  18.  
  19. #include "bibutils.h"
  20. #include "BibTeX.h"
  21. #include "bibext.h"
  22. #include "file-io.h"
  23. #include "CBibTeXApp.h"
  24. #include <LGrowZone.h>
  25.  
  26. int             debug = FALSE;
  27. int             verbose = TRUE;
  28.  
  29. int             BibTeX_dot = TRUE; /* flag which shows dot in ilg being active */
  30.  
  31. const char      *aux_fn;
  32. const char      *dbg_fn;
  33.  
  34. FileDesc        gAuxDesc;
  35. FileDesc        gDbgDesc;
  36.  
  37. // Local variables:
  38.  
  39. static char     base[FILENAME_MAX];
  40.  
  41. long totmem = 0L;                       /* for debugging memory usage */
  42.  
  43. // Local functions:
  44. static  void    Bibtex(void);
  45. static void chknew(size_t size);
  46. static void check_aux(char *fn);
  47. static  void    FreeMemory(void);
  48. static  void    InitializeBibtex(void);
  49.  
  50. #ifdef MAX
  51. #undef MAX
  52. #endif
  53. #define MAX(a,b)        ( ((a) > (b)) ? (a) : (b) )
  54.  
  55. /**************************************************************************
  56. *                                                                         *
  57. * Function:   InvokeBibtex                                             *
  58. * Purpose:    This function merely invokes the main Bibtex function.   *
  59. * Inputs:     None.                                                       *
  60. * Outputs:    None.                                                       *
  61. * Exceptions: Catches any exceptions thrown inside of Bibtex.          *
  62. * Side Effects:   None.                                                   *
  63. * Design:     This function is just a wrapper for Bibtex.  It allows   *
  64. *             me to catch any exceptions thrown while Bibtex does its  *
  65. *             processing.                                                 *
  66. * Errors:     None.                                                       *
  67. * History:                                                                *
  68. *     1.0     29-Jul-95   RJZ.  Initial version.                          *
  69. *                                                                         *
  70. **************************************************************************/
  71. void InvokeBibtex(void) {
  72.  
  73.                                         // Any call to FATAL or FatalOSErr is
  74.                                         // caught by this exception handler.
  75.     try {
  76.         Bibtex();
  77.     }
  78.     catch (...) {
  79.         CloseAllFiles();
  80.     }
  81. }
  82.  
  83. /**********************************************************************
  84. *                                                                     *
  85. * Function:   OneTimeInitialization                                   *
  86. * Purpose:    Performs any initialization of Bibtex that needs to  *
  87. *             happen just once at program start-up.                   *
  88. * Inputs:     None.                                                   *
  89. * Outputs:    Returns an error code if there was a problem with       *
  90. *             initialization.                                         *
  91. * Exceptions: None.                                                   *
  92. * Side Effects:   None.                                               *
  93. * Errors:     None.                                                   *
  94. * History:                                                            *
  95. *     1.0     29-Jul-95   RJZ.  Initial version.                      *
  96. *                                                                     *
  97. **********************************************************************/
  98. OSErr OneTimeInitialization(void) {
  99.     OSErr   err = noErr;
  100.  
  101.     return err;
  102. }
  103.  
  104. /************************************************************************
  105. *                                                                       *
  106. * Function:   InitializeBibtex                                       *
  107. * Purpose:    This function performs initialization that must be done   *
  108. *             every time we process a new aux file.  It also invokes    *
  109. *             initializers for all other Bibtex modules.             *
  110. * Inputs:     None.                                                     *
  111. * Outputs:    None.                                                     *
  112. * Exceptions: None.                                                     *
  113. * Side Effects:   Initializes plenty of global varialbes.               *
  114. * Design:     Each module has its own initializer so that I don't have  *
  115. *             to increase the scope of the global variables defined     *
  116. *             within that module.                                       *
  117. * Errors:     None.                                                     *
  118. * History:                                                              *
  119. *     1.0     29-Jul-95   RJZ.  Initial version.                        *
  120. *                                                                       *
  121. ************************************************************************/
  122. static void InitializeBibtex(void) {
  123.  
  124.                                         // Initialize the file reference
  125.                                         // numbers to zero indicating that none
  126.                                         // of these files are open.
  127.     gAuxDesc.refNum = 0;
  128.     gDbgDesc.refNum = 0;
  129.     totmem = 0L;
  130. }
  131.  
  132.  
  133. /***********************************************************************
  134. *                                                                      *
  135. * Function:   Bibtex                                                *
  136. * Purpose:    This is pretty much the entire Bibtex program.        *
  137. * Inputs:     None.                                                    *
  138. * Outputs:    None.                                                    *
  139. * Exceptions: Throws an exception if there is an OS error while        *
  140. *             initializing.                                            *
  141. * Side Effects:   Lots of them.  They are all warts from the original  *
  142. *             program.                                                 *
  143. * Design:     Original design by Pehong Chen.  See copyright notice.   *
  144. * Errors:     Prints error messages in the log window as they occur.   *
  145. * History:                                                             *
  146. *     1.0     13-Jul-95   RJZ.  Initial version.                       *
  147. *                                                                      *
  148. ***********************************************************************/
  149. static void Bibtex(void) {
  150.     InitializeBibtex();
  151.                                         // The program name won¥'t be coming
  152.                                         // from the command line, so set it
  153.                                         // here.
  154.  
  155.  
  156.     OSErr err;
  157.     extern FInfo    AuxFileInfo;            // Finder info for aux file
  158.                                         // Determine creator of aux file
  159.  
  160.     err = ::FSpGetFInfo(&gAuxDesc.spec, &AuxFileInfo);
  161.     if (err != noErr)
  162.         FatalOSErr("Error getting Finder information for aux file: %s", err);
  163.     
  164.     vince_main();
  165.     
  166.     //FPrintFStdErr("Transcript written in %s.¥r", blg_fn);
  167.     chkfree();                          /* free dynamic chunk space */
  168.     CloseAllFiles();
  169. }
  170.  
  171. /*--------------------------------------------------------------------*/
  172.  
  173. /***********************************************************************
  174. malloc() implementations themselves usually allocate large chunks of
  175. memory of fixed size in which they suballocate requests with
  176. additional overhead of pointers, lengths, and alignment requirements.
  177. Experiments with the program in tstmall.c indicate a typical policy of
  178. aligning the request to a double-word boundary, then adding space for
  179. two extra words.  Thus, allocation of a single byte uses up 24 bytes!
  180. When a large chunk is used up, another large chunk is allocated with
  181. an additional overhead of two more words.  Thus, we should allocate
  182. our own chunks in sizes of malloc() large chunk sizes, less the
  183. two-word/chunk malloc() overhead, and less our chunk pointer size.  On
  184. some systems, optimal choice of CHUNKSIZE is critical if space is not
  185. to be seriously wasted; a value of 2048 is best for DECstation ULTRIX
  186. 4.3.
  187. ***********************************************************************/
  188.  
  189. #ifndef CHUNKSIZE               /* can specify at compile time */
  190. #define CHUNKSIZE       2048    /* suitable for most systems */
  191.  
  192. #if defined(__alpha) && defined(__unix__)
  193. #undef CHUNKSIZE
  194. #define CHUNKSIZE       2040    /* for DEC Alpha OSF/1 2.x */
  195. #endif
  196.  
  197. #if defined(__host_mips) && defined(_SYSTYPE_SYSV) && !defined(__sgi)
  198. #undef CHUNKSIZE
  199. #define CHUNKSIZE       16892   /* weird size for MIPS RC6280 EP/IX 2.1.1 */
  200. #endif
  201.  
  202. #endif /* CHUNKSIZE */
  203.  
  204. #ifndef MAXCHUNK
  205. #define MAXCHUNK        (CHUNKSIZE - 2*sizeof(void*) - 2*sizeof(void*))
  206. #endif
  207.  
  208. typedef struct KCHUNK {
  209.     struct KCHUNK       **prev;          /* handle to previous chunk */
  210.     char                *end; /* address of byte following end of storage[] */
  211.     char                storage[1];     /* space for this chunk */
  212. } CHUNK, *CHUNK_PTR, **ChunkHandle;
  213.  
  214. static ChunkHandle chkhead = (ChunkHandle) NULL; // Handle to chain of chunks
  215. static char     *chknext = (char*)NULL; /* next available in current chunk */
  216. static long     chktotal = 0L;          /* total bytes allocated */
  217.  
  218. typedef struct chk_remember {
  219.     struct chk_remember *next;
  220.     char* offset;
  221.     ChunkHandle handle;
  222. } chk_remember;
  223.  
  224. static chk_remember* chk_store_head = NULL;
  225. static chk_remember* chk_store = NULL;
  226.  
  227. void unlockhandles(void) {
  228.     ChunkHandle ch;
  229.     for (ch = chkhead ;ch;  ) {
  230.         HUnlock((Handle) ch);
  231.         ch = (**ch).prev;
  232.     }
  233. }
  234.  
  235. void lockhandles(void) {
  236.     ChunkHandle ch;
  237.     for (ch = chkhead ;ch;  ) {
  238.         HLockHi((Handle) ch);
  239.         ch = (**ch).prev;
  240.     }
  241. }
  242.  
  243. extern CBibtexApp* theAppPointer;
  244.  
  245. void cede_time(void){
  246.     unlockhandles();
  247.     theAppPointer->ProcessNextEvent();
  248.     lockhandles();
  249. }
  250.  
  251. /*********************************************************************
  252. *                                                                    *
  253. * Function:   FreeMemory                                             *
  254. * Purpose:    Frees the memory chunks that we have allocated.        *
  255. * Inputs:     None.                                                  *
  256. * Outputs:    None.                                                  *
  257. * Exceptions: None.                                                  *
  258. * Side Effects:   Frees memory and changes the value of some global  *
  259. *                 variables.                                         *
  260. * Errors:     None.                                                  *
  261. * History:                                                           *
  262. *     1.1     16-Mar96    RJZ.  Initial version.                     *
  263. *                                                                    *
  264. *********************************************************************/
  265. static void FreeMemory(void) {
  266.     ChunkHandle oldChunkHead;
  267.  
  268.     while (chkhead != (ChunkHandle) NULL) {
  269.         oldChunkHead = chkhead;
  270.         chkhead = (**chkhead).prev;
  271.         DisposeHandle((Handle) oldChunkHead);
  272.     }
  273.     chktotal = 0L;
  274.     chkhead = (ChunkHandle) NULL;
  275.     chknext = (char *) NULL;
  276.     
  277.     chk_remember* next_chk_store;
  278.     for(chk_store = chk_store_head; chk_store; ){
  279.         next_chk_store = chk_store->next;
  280.         delete chk_store;
  281.         chk_store = next_chk_store;
  282.     }
  283. }
  284.  
  285. /**************************************************************************
  286. *                                                                         *
  287. * Function:   chkalloc                                                    *
  288. * Purpose:    Allocates a chunk of memory.                                *
  289. * Inputs:     size is the number of bytes to allocate.  alignment_size    *
  290. *             specifies how the chunk should be aligned in memory.  1 =   *
  291. *             byte, 2 = short, 4 = long.                                  *
  292. * Outputs:    Returns a pointer to the memory allocated.                  *
  293. * Exceptions: None.                                                       *
  294. * Side Effects:   Allocates memory.                                       *
  295. * Design:     First try to allocate the memory in the application heap.   *
  296. *             If that fails, allocate the memory in the system heap.      *
  297. *             Note that after allocating this handle based memory, it     *
  298. *             must remain locked until it is freed.                       *
  299. * Errors:     None.                                                       *
  300. * History:                                                                *
  301. *     1.0     20-Jul-95   RJZ.  Changed this function so that the chunks  *
  302. *                         are handle based rather than pointed based.     *
  303. *                                                                         *
  304. **************************************************************************/
  305. void *chkalloc(size_t size, size_t alignment_size) {
  306.     char *p;
  307.  
  308.                                         // If the head of the chunk list is
  309.                                         // NULL, then this is the first call.
  310.     if (chkhead == (ChunkHandle) NULL){
  311.         chknew(size);
  312.         // store the first one so we can zip through the
  313.         // list later front to back to find out pointers
  314.         // again
  315.         chk_store_head = new chk_remember;
  316.         chk_store = 0;
  317.     }
  318.     
  319.     if (alignment_size < 1)
  320.         alignment_size = 1;
  321.     chknext = (char*)((long)(chknext + alignment_size - 1) &
  322.                       ~(alignment_size - 1));
  323.     if ((chknext + size) > (**chkhead).end)
  324.         chknew(size);
  325.  
  326.     p = chknext;
  327.     chknext += size;
  328.     
  329.     if(chk_store != 0) {
  330.         chk_store->next = new chk_remember;
  331.         chk_store = chk_store->next;
  332.     } else {
  333.         chk_store = chk_store_head;
  334.     }
  335.     // remember what we did
  336.     chk_store->handle = chkhead;
  337.     chk_store->offset = (char*) (p - ((**chkhead).storage));
  338.     chk_store->next = 0;
  339.     
  340.     return ((void*)p);
  341. }
  342.  
  343. void *ptohrealloc(short reset) {
  344.     static chk_remember* chk_iterator;
  345.     if(reset == 1){
  346.         chk_iterator = chk_store_head;
  347.         return 0;
  348.         
  349.     }
  350.     char* p;
  351.     p = (char*) ( (long)((**(chk_iterator->handle)).storage)
  352.                    + (long)(chk_iterator->offset));
  353.     chk_iterator = chk_iterator->next;
  354.     return p;
  355. }
  356.  
  357. /************************************************************************
  358. *                                                                       *
  359. * Function:   chkfree                                                   *
  360. * Purpose:    Frees all the dynamically allocated chunks of memory.     *
  361. * Inputs:     None.                                                     *
  362. * Outputs:    None.                                                     *
  363. * Exceptions: None.                                                     *
  364. * Side Effects:   Frees memory.  Writes the total number of bytes       *
  365. *             allocated to the message window and the log file.         *
  366. * Design:     The chunks of memory form a linked list.  Start at the    *
  367. *             head of the list and free each chunk.                     *
  368. * Errors:     None.                                                     *
  369. * History:                                                              *
  370. *     1.0     20-Jul-95   RJZ.  Changed this function so that it knows  *
  371. *                         that the chunks are handle based.             *
  372. *     1.1     16-Mar-96   RJZ.  The freeing of the memory is in a       *
  373. *                         separate function now.                        *
  374. *                                                                       *
  375. ************************************************************************/
  376. void chkfree(VOID_ARG) {
  377.  
  378.     MESSAGE("Dynamic memory allocated: %ld bytes.¥r", chktotal);
  379.     FPrintFStdErr("¥rBibTeX run complete.¥r");
  380.     FreeMemory();
  381. }
  382.  
  383. /**************************************************************************
  384. *                                                                         *
  385. * Function:   chknew                                                      *
  386. * Purpose:    Allocates a new chunk of memory.                            *
  387. * Inputs:     size is the size of the memory to be allocated.             *
  388. * Outputs:    None.                                                       *
  389. * Exceptions: Throws an exception if unable to allocate the memory.       *
  390. * Side Effects:   Dynamically allocates memory.                           *
  391. * Design:     First try to allocate a block of memory in the application  *
  392. *             heap.  If that fails, try using temporary memory.  This is  *
  393. *             the only place that Bibtex allocates memory.             *
  394. * Errors:     Writes an error message if both allocations fail.           *
  395. * History:                                                                *
  396. *     1.0     20-Jul-95   RJZ.  Changed so that the blocks are handle     *
  397. *                         based.  This allows Bibtex to use temporary  *
  398. *                         memory if the application memory is exhausted.  *
  399. *     1.1     16-Mar-96   RJZ.  If memory allocation fails, free memory   *
  400. *                         before printing an error message.  This helps   *
  401. *                         to insure that the message will appear!  Also,  *
  402. *                         allocate temp memory first.  When that's        *
  403. *                         finished, begin allocating from the             *
  404. *                         application heap.  Only use the application     *
  405. *                         heap if the memory reserve is still available.  *
  406. *                                                                         *
  407. **************************************************************************/
  408. static void chknew(size_t size) {
  409.     size_t      chunk_size;
  410.     OSErr       err;
  411.     ChunkHandle new_chkhead;
  412.  
  413.     chunk_size = MAX(size,MAXCHUNK) + sizeof(ChunkHandle) + sizeof(char*);
  414.  
  415.     new_chkhead = (ChunkHandle) TempNewHandle(chunk_size, &err);
  416.     if (new_chkhead == NULL) {
  417.         LGrowZone *growZone = LGrowZone::GetGrowZone();
  418.         if (!growZone->MemoryIsLow())
  419.             new_chkhead = (ChunkHandle) NewHandle(chunk_size);
  420.     }
  421.                                         // When memory is exhausted, tell the
  422.                                         // user how far we got before quitting.
  423.  
  424.     if (new_chkhead == (ChunkHandle) NULL) {
  425.         FreeMemory();
  426.         err = MemError();
  427.         MESSAGE("Current input file  = %s¥r", aux_fn);
  428.         //MESSAGE("Current line number = %ld¥r", (long)BibTeX_lc);
  429.         //MESSAGE("Current entry total = %ld¥r", (long)BibTeX_tt);
  430.         FATAL("Not enough core...abort.¥r%s", "");
  431.     }
  432.     HLockHi((Handle) new_chkhead);
  433.                                         // track total bytes allocated
  434.     chktotal += chunk_size;
  435.                                         // for debugging only
  436.  
  437.     (void) memset(*new_chkhead,-1,chunk_size);
  438.  
  439.                                         // attach to head of chunk chain
  440.     (**new_chkhead).prev = chkhead;
  441.     chkhead = new_chkhead;
  442.     (**chkhead).end = (char *) *chkhead + (int)chunk_size;
  443.  
  444.                                         // chknext points to the next available
  445.                                         // byte in the storage area.  For a new
  446.                                         // chunk, this is just the first byte.
  447.     chknext = (**chkhead).storage;
  448. }
  449.  
  450.  
  451. /**************************************************************************
  452. *                                                                         *
  453. * Function:   FormatOSErr                                                 *
  454. * Purpose:    Formats a Macintosh OS error into a C string.               *
  455. * Inputs:     error is a non-zero OS error returned by an OS call.        *
  456. *             buffer points to a buffer where the text equivalent of the  *
  457. *             error code should be stored.                                *
  458. * Outputs:    buffer gets filled with the text equivalent of the error    *
  459. *             code.                                                       *
  460. * Exceptions: None.                                                       *
  461. * Side Effects:   None.                                                   *
  462. * Design:     This function knows the meaning of the most common error    *
  463. *             messages.  If it encounters one it doesn't know, it         *
  464. *             converts the number to a string and uses that.              *
  465. * Errors:     None.                                                       *
  466. * History:                                                                *
  467. *     1.0     10-Jul-95   RJZ.  Original version.                         *
  468. *                                                                         *
  469. **************************************************************************/
  470. void FormatOSErr(OSErr error, char *buffer) {
  471.     char    *errorString = NULL;
  472.  
  473.     switch (error) {
  474.     case dirFulErr:                     // -33
  475.         errorString = "File directory full";
  476.         break;
  477.     case dskFulErr:                     // -34
  478.         errorString = "Disk is full";
  479.         break;
  480.     case nsvErr:                        // -35
  481.         errorString = "No such volume";
  482.         break;
  483.     case ioErr:                         // -36
  484.         errorString = "I/O error";
  485.         break;
  486.     case bdNamErr:                      // -37
  487.         errorString = "Bad filename";
  488.         break;
  489.     case fnOpnErr:                      // -38
  490.         errorString = "File not open";
  491.         break;
  492.     case eofErr:                        // -39
  493.         errorString = "End of file";
  494.         break;
  495.     case tmfoErr:                       // -42
  496.         errorString = "Too many files open";
  497.         break;
  498.     case fnfErr:                        // -43
  499.         errorString = "File not found";
  500.         break;
  501.     case wPrErr:                        // -44
  502.         errorString = "Hardware volume lock";
  503.         break;
  504.     case fLckdErr:                      // -45
  505.         errorString = "File is locked";
  506.         break;
  507.     case vLckdErr:                      // -46
  508.         errorString = "Software volume lock";
  509.         break;
  510.     case fBsyErr:                       // -47
  511.         errorString = "File is busy";
  512.         break;
  513.     case dupFNErr:                      // -48
  514.         errorString = "Duplicate filename and version";
  515.         break;
  516.     case opWrErr:                       // -49
  517.         errorString = "File already open for writing";
  518.         break;
  519.     case paramErr:                      // -50
  520.         errorString = "No default volume";
  521.         break;
  522.     case rfNumErr:                      // -51
  523.         errorString = "Bad reference number";
  524.         break;
  525.     case permErr:                       // -54
  526.         errorString = "Attempt to open locked file for writing";
  527.         break;
  528.     case nsDrvErr:                      // -56
  529.         errorString = "No such drive";
  530.         break;
  531.     case wrPermErr:                     // -61
  532.         errorString = "Write permission error";
  533.         break;
  534.     case dirNFErr:                      // -120
  535.         errorString = "Directory not found or incomplete pathname";
  536.         break;
  537.     case afpAccessDenied:               // -5000
  538.         errorString = "User does not have the correct access";
  539.         break;
  540.     case afpObjectTypeErr:              // -5025
  541.         errorString = "Directory not found or incomplete pathname";
  542.         break;
  543.     default:
  544.         NumToString(error, (StringPtr) buffer);
  545.         (void) P2CStr((StringPtr) buffer);
  546.         break;
  547.     }
  548.     if (errorString != NULL)
  549.         strcpy(buffer, errorString);
  550. }
  551.  
  552. /**************************************************************************
  553. *                                                                         *
  554. * Function:   FatalOSErr                                                  *
  555. * Purpose:    Formats and prints a fatal error that occurs as the result  *
  556. *             of an OS call.                                              *
  557. * Inputs:     mess points to the first argument of a call to fprintf.     *
  558. *             error is the OS error that occurred.  In the overloaded     *
  559. *             versions, the additional inputs are inputs to fprintf.      *
  560. * Outputs:    None.                                                       *
  561. * Exceptions: Throws an exception.  Note that "throw" needs an argument   *
  562. *             unless it is used within a catch handler.  Use a dummy      *
  563. *             NULL argument here.                                         *
  564. * Side Effects:   Prints an error message.                                *
  565. * Errors:     Prints an error message.                                    *
  566. * History:                                                                *
  567. *     1.0     10-Jul-95   RJZ.  Initial version.                          *
  568. *                                                                         *
  569. **************************************************************************/
  570. void CloseAllFilesAfterError(void);
  571.  
  572. void FatalOSErr(const char *mess, OSErr error) {
  573.     char    buffer[kBufferSize];
  574.     Str255  message;
  575.  
  576.     FormatOSErr(error, buffer);
  577.     message[0] = sprintf((char *) message + 1, mess, buffer);
  578.     CBibtexApp::PostErrorAlert(message);
  579.     CloseAllFilesAfterError();
  580.     throw NULL;
  581. }
  582.  
  583. void FatalOSErr(const char *mess, const char *mess1, OSErr error) {
  584.     char    buffer[kBufferSize];
  585.     Str255  message;
  586.  
  587.     FormatOSErr(error, buffer);
  588.     message[0] = sprintf((char *) message + 1, mess, mess1, buffer);
  589.     CBibtexApp::PostErrorAlert(message);
  590.     CloseAllFilesAfterError();
  591.     throw NULL;
  592. }
  593.  
  594. /**************************************************************************
  595. *                                                                         *
  596. * Function:   ReportOSErr                                                 *
  597. * Purpose:    Formats and displays an error message.  This is just like   *
  598. *             FatalOSErr except that it is not fatal.                     *
  599. * Inputs:     mess is a pointer to a message string.  error is an OSErr.  *
  600. *             This function converts OSErr to a string and then inserts   *
  601. *             it into mess where the %s appears.                          *
  602. * Outputs:    None.                                                       *
  603. * Exceptions: None.                                                       *
  604. * Side Effects:   Displays an alert.                                      *
  605. * Errors:     None.                                                       *
  606. * History:                                                                *
  607. *     1.0     29-Jul-95   RJZ.  Initial version.                          *
  608. *                                                                         *
  609. **************************************************************************/
  610. void ReportOSErr(const char *mess, OSErr error) {
  611.     char    buffer[kBufferSize];
  612.     Str255  message;
  613.  
  614.     FormatOSErr(error, buffer);
  615.     message[0] = sprintf((char *) message + 1, mess, buffer);
  616.     CBibtexApp::PostErrorAlert(message);
  617. }
  618.  
  619. /************************************************************************
  620. *                                                                       *
  621. * Function:   CloseAllFiles                                             *
  622. * Purpose:    Closes all files that Bibtex may be using.  CloseFile  *
  623. *             checks to see if the file is actually open before trying  *
  624. *             to close it, so there's no harm in calling it for every   *
  625. *             file that Bibtex might be using.                       *
  626. * Inputs:     None.                                                     *
  627. * Outputs:    None.                                                     *
  628. * Exceptions: None.                                                     *
  629. * Side Effects:   May close files.                                      *
  630. * Errors:     None.                                                     *
  631. * History:                                                              *
  632. *     1.0     29-Jul-95   RJZ.  Initial version.                        *
  633. *                                                                       *
  634. ************************************************************************/
  635. void CloseAllFiles(void) {
  636.     CloseOutputFile(&gDbgDesc);
  637.     CloseAllFilesAfterError();
  638. }
  639.  
  640. /**************************************************************************
  641. *                                                                         *
  642. * Function:   SetBibtexOptions                                         *
  643. * Purpose:    Sets Bibtex options to the values indicated by its       *
  644. *             parameters.                                                 *
  645. * Inputs:     germanOrdering is the same as the original -g option,       *
  646. *             compressBlanks is the -c option, letterOrdering is the -l   *
  647. *             option, and debugOn is the -d option.  initPage is the -p   *
  648. *             option.  If evenOdd is -1, then pageNo contains a starting  *
  649. *             page number.  If evenOdd is 0, then the user has selected   *
  650. *             the "any" option.  If evenOdd is 1, the user has selected   *
  651. *             the "odd" option.  If evenOdd is 2, the user has selected   *
  652. *             the "even" option.                                          *
  653. * Outputs:    None.                                                       *
  654. * Exceptions: None.                                                       *
  655. * Side Effects:   All option variables are global.  This function sets    *
  656. *             them.                                                       *
  657. * Design:     Since pageNo is a Pascal string, it may contain as many as  *
  658. *             255 characters.  If this string is longer than              *
  659. *             NUMBER_MAX-1, quietly truncate it.  If the user tried to    *
  660. *             enter a starting page number but didn't actually type a     *
  661. *             number, use zero instead.                                   *
  662. * Errors:     None.                                                       *
  663. * History:                                                                *
  664. *     1.0     29-Jul-95   RJZ.  Initial version.                          *
  665. *                                                                         *
  666. **************************************************************************/
  667. void SetBibtexOptions(Boolean    debugOn)
  668. {
  669.     debug = debugOn;
  670. }
  671.  
  672. /************************************************************************
  673. *                                                                       *
  674. * Function:   GetBibtexOptions                                       *
  675. * Purpose:    Gets the current settings of Bibtex options.  The      *
  676. *             application calls this function so it can initialize the  *
  677. *             values of the options before displaying the options       *
  678. *             dialog.                                                   *
  679. * Inputs:     None.                                                     *
  680. * Outputs:    They are the same as the input parameters for             *
  681. *             SetBibtexOptions.                                      *
  682. * Exceptions: None.                                                     *
  683. * Side Effects:   None.                                                 *
  684. * Errors:     None.                                                     *
  685. * History:                                                              *
  686. *     1.0     29-Jul-95   RJZ.  Initial version.                        *
  687. *                                                                       *
  688. ************************************************************************/
  689. void GetBibtexOptions(Boolean&   debugOn)
  690. {
  691.     debugOn = debug == TRUE;
  692. }
  693.  
  694. /**************************************************************************
  695. *                                                                         *
  696. * Function:   GetWindowTitle                                              *
  697. * Purpose:    Determines the title of the log window.                     *
  698. * Inputs:     None.                                                       *
  699. * Outputs:    outName is the title that the log window will have.         *
  700. * Exceptions: None.                                                       *
  701. * Side Effects:   None.                                                   *
  702. * Design:     Note that this function relies on base having an            *
  703. *             appropriate value.  This means that there should have been  *
  704. *             a call to IntroduceIdxFile.                                 *
  705. * Errors:     None.                                                       *
  706. * History:                                                                *
  707. *     1.0     29-Jul-95   RJZ.  Initial version.                          *
  708. *                                                                         *
  709. **************************************************************************/
  710. void GetWindowTitle(StringPtr outName) {
  711.  
  712.     outName[0] = sprintf((char *) outName + 1, "Log for ¥"%s¥"", base);
  713. }
  714.  
  715. /**************************************************************************
  716. *                                                                         *
  717. * Function:   check_aux                                                   *
  718. * Purpose:    Extracts the base name of the idx file (everything to the   *
  719. *             left of ".idx") and tries to open the file if open_fn is    *
  720. *             true.  Also determines the size of the idx file.  Be sure   *
  721. *             to call this function immediately after getting the name    *
  722. *             of the idx file.                                            *
  723. * Inputs:     fn is a pointer the idx file name.  open_fn is true if we   *
  724. *             should try to open the file, false otherwise.               *
  725. * Outputs:    None.                                                       *
  726. * Exceptions: If this function is unable to open the file or unable to    *
  727. *             determine the size of the file, it throws an exception.     *
  728. * Side Effects:   Sets the value of "base" which is the base name of the  *
  729. *                 idx file.  Also sets the value of gIdxFileSize to the   *
  730. *                 number of bytes in the idx file.                        *
  731. * Design:     In its original form, this function expected fn to be a     *
  732. *             path to the idx file.  The Macintosh file system does not   *
  733. *             normally use a path to specify a file.  Instead it uses an  *
  734. *             File System Specification (FSSpec) record.  This function   *
  735. *             expects that the FSSpec record for the idx file (gIdxSpec)  *
  736. *             has been filled in prior to entry.  fn points to just the   *
  737. *             file name and it is no longer a path to the file.           *
  738. *                                                                         *
  739. *             Note that some of the error conditions that this function   *
  740. *             checks will no longer occur.  For example, the file name    *
  741. *             will never be too long (since the user selected the file    *
  742. *             via a StandardGetFile dialog).  Also, if the function that  *
  743. *             opens the file fails, it will throw an exception.  We will  *
  744. *             never see a return code of 0 from OPEN_IN.                  *
  745. * Errors:     Reports an error if unable to determine the size of the     *
  746. *             file.                                                       *
  747. * History:                                                                *
  748. *     1.0     10-Jul-95   RJZ.  Replaced most Unix I/O calls with their   *
  749. *                         Macintosh equivalents.  The ones that remain    *
  750. *                         will never get called.  This function now       *
  751. *                         determines the size of the idx file.  This is   *
  752. *                         so Bibtex can buffer the input from this     *
  753. *                         file.                                           *
  754. *                                                                         *
  755. **************************************************************************/
  756. static void check_aux(char *fn) {
  757.     char        *ptr = fn;
  758.     char        *ext;
  759.     int         with_ext = FALSE;
  760.     int         i = 0;
  761.  
  762.     ext = strrchr(fn, EXT_DELIM);
  763.     if ((ext != NULL) && (ext != fn) && (*(ext + 1) != DIR_DELIM)) {
  764.         with_ext = TRUE;
  765.         while ((ptr != ext) && (i < sizeof(base)))
  766.             base[i++] = *ptr++;
  767.     } else
  768.         while ((*ptr != NUL) && (i < sizeof(base)))
  769.             base[i++] = *ptr++;
  770.  
  771.     if (i < sizeof(base))
  772.         base[i] = NUL;
  773.     else
  774.         FATAL2("Index file name %s too long (max %u).¥r",
  775.                base, (unsigned int)sizeof(base));
  776.  
  777.     aux_fn = fn;
  778.  
  779. }
  780. /**************************************************************************
  781. *                                                                         *
  782. * Function:   IntroduceBtxFile                                            *
  783. * Purpose:    Tells Bibtex about the idx file we are about to          *
  784. *             process.  It fills in the FSSpec record of the file         *
  785. *             descriptor for the idx file and initializes the variable    *
  786. *             aux_fn to point to the name of the idx file.  It also       *
  787. *             invokes check_aux which performs some other initialization  *
  788. *             such as extracting the base name of the file.               *
  789. * Inputs:     specPtr is a pointer to the FSSpec record of the idx file   *
  790. *             we're getting ready to process.                             *
  791. * Outputs:    None.                                                       *
  792. * Exceptions: None.                                                       *
  793. * Side Effects:   Initializes the FileDescriptor structure for the idx    *
  794. *             file.                                                       *
  795. * Design:     fns used to be an array of input files.  Now it's just an   *
  796. *             array with one element since we process just one idx file.  *
  797. *             I couldn't think of a good way to reproduce this            *
  798. *             capability on the Macintosh.  I'm not really sure it's      *
  799. *             necessary either.                                           *
  800. *             This function uses a trick that appears in several other    *
  801. *             places in this program.  The name field of the FSSpec       *
  802. *             record is declared to be a Str63 even though the maximum    *
  803. *             length of a file name is 31 characters.  Thus, it's always  *
  804. *             safe to store a null character at the end of this string.   *
  805. *             Then, a pointer to the first character of the string        *
  806. *             points to a C style string.  A pointer to the length byte   *
  807. *             points to a Pascal style string.                            *
  808. * Errors:     None.                                                       *
  809. * History:                                                                *
  810. *     1.0     29-Jul-95   RJZ.  Initial version.                          *
  811. *                                                                         *
  812. **************************************************************************/
  813. void IntroduceBtxFile(FSSpecPtr specPtr) {
  814.  
  815.     gAuxDesc.spec = *specPtr;
  816.     gAuxDesc.spec.name[StrLength(gAuxDesc.spec.name) + 1] = '¥0';
  817.     aux_fn = (char *) gAuxDesc.spec.name + 1;
  818.     // setup base name
  819.     check_aux((char *) aux_fn);
  820. }
  821.